﻿Public Class MembershipProvider
    Inherits System.Web.Security.MembershipProvider
    Implements IMembershipProvider

#Region " Private Members "

    Private _enablePasswordReset As Boolean
    Private _enablePasswordRetrieval As Boolean
    Private _maxInvalidPasswordAttempts As Integer
    Private _minRequiredNonalphanumericCharacters As Integer
    Private _minRequiredPasswordLength As Integer
    Private _passwordAttemptWindow As Integer
    Private _passwordFormat As System.Web.Security.MembershipPasswordFormat
    Private _passwordStrengthRegularExpression As String
    Private _requiresQuestionAndAnswer As Boolean
    Private _requiresUniqueEmail As Boolean
    Private _userIsOnlineTimeWindow As Integer
    Private _applicationName As String
    Private _remoteProviderName As String
    Private _service As New MembershipProviderService.MembershipProvider()

#End Region

#Region " Private Methods "

    Private Function ConvertUser(ByVal user As System.Web.Security.MembershipUser) As MembershipProviderService.MembershipUser

        If user Is Nothing Then
            Return Nothing
        End If

        Dim membershipUser As New MembershipProviderService.MembershipUser()
        With membershipUser
            .Comment = user.Comment
            .CreationDate = user.CreationDate
            .Email = user.Email
            .IsApproved = user.IsApproved
            .IsLockedOut = user.IsLockedOut
            .IsOnline = user.IsOnline
            .LastActivityDate = user.LastActivityDate
            .LastLockoutDate = user.LastLockoutDate
            .LastLoginDate = user.LastLoginDate
            .LastPasswordChangedDate = user.LastPasswordChangedDate
            .PasswordQuestion = user.PasswordQuestion
            .ProviderName = user.ProviderName
            .ProviderUserKey = user.ProviderUserKey
            .UserName = user.UserName
        End With

        Return membershipUser

    End Function

    Private Function ConvertUser(ByVal user As MembershipProviderService.MembershipUser) As System.Web.Security.MembershipUser

        If user Is Nothing Then
            Return Nothing
        End If

        Return New System.Web.Security.MembershipUser(Me.Name, user.UserName, user.ProviderUserKey, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreationDate, user.LastLoginDate, user.LastActivityDate, user.LastPasswordChangedDate, user.LastLockoutDate)

    End Function

    Private Function BuildUserCollection(ByVal list() As MembershipProviderService.MembershipUser) As System.Web.Security.MembershipUserCollection

        Dim collection As System.Web.Security.MembershipUserCollection = New System.Web.Security.MembershipUserCollection()

        If list IsNot Nothing Then
            For Each user As MembershipProviderService.MembershipUser In list
                collection.Add(ConvertUser(user))
            Next
        End If

        Return collection

    End Function

    Private Sub PrepareConfigFromWebService(ByVal config As System.Collections.Specialized.NameValueCollection)

        If config("remoteProviderName") Is Nothing OrElse config("remoteProviderName").ToString.Length = 0 Then
            Throw New Exception("remoteProviderName attribute did not set!")
        Else
            _remoteProviderName = config("remoteProviderName")
        End If

        If config("roleProviderUri") IsNot Nothing AndAlso config("roleProviderUri").ToString.Length > 0 Then
            _service.Url = config("roleProviderUri")
        End If

        Dim providerSettings() As MembershipProviderService.ProviderSetting = _service.GetProviderSettings(RemoteProviderName, ApplicationName)

        If config Is Nothing Then
            config = New System.Collections.Specialized.NameValueCollection
        End If

        For Each providerSetting As MembershipProviderService.ProviderSetting In providerSettings
            If config(providerSetting.Name) Is Nothing Then
                config.Add(providerSetting.Name, providerSetting.Value)
            Else
                config(providerSetting.Name) = providerSetting.Value
            End If
        Next

        If config("applicationname") Is Nothing Then
            config.Add("applicationname", "/")
        End If

        If config("applicationname").ToString.Length = 0 Then
            _applicationName = "/"
            config("applicationname") = "/"
        Else
            _applicationName = config("applicationname")
        End If

    End Sub

#End Region

#Region " Public Properties "

    Public Property RemoteProviderName() As String Implements IMembershipProvider.RemoteProviderName
        Get
            Return _remoteProviderName
        End Get
        Set(ByVal value As String)
            _remoteProviderName = value
        End Set
    End Property

    Public Overrides Property ApplicationName() As String Implements IMembershipProvider.ApplicationName
        Get
            Return _applicationName
        End Get
        Set(ByVal value As String)
            _applicationName = value
        End Set
    End Property

    Public Overrides ReadOnly Property EnablePasswordReset() As Boolean Implements IMembershipProvider.EnablePasswordReset
        Get
            Return _enablePasswordReset
        End Get
    End Property

    Public Overrides ReadOnly Property EnablePasswordRetrieval() As Boolean Implements IMembershipProvider.EnablePasswordRetrieval
        Get
            Return _enablePasswordRetrieval
        End Get
    End Property

    Public Overrides ReadOnly Property MaxInvalidPasswordAttempts() As Integer Implements IMembershipProvider.MaxInvalidPasswordAttempts
        Get
            Return _maxInvalidPasswordAttempts
        End Get
    End Property

    Public Overrides ReadOnly Property MinRequiredNonAlphanumericCharacters() As Integer Implements IMembershipProvider.MinRequiredNonAlphanumericCharacters
        Get
            Return _minRequiredNonalphanumericCharacters
        End Get
    End Property

    Public Overrides ReadOnly Property MinRequiredPasswordLength() As Integer Implements IMembershipProvider.MinRequiredPasswordLength
        Get
            Return _minRequiredPasswordLength
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordAttemptWindow() As Integer Implements IMembershipProvider.PasswordAttemptWindow
        Get
            Return _passwordAttemptWindow
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordFormat() As System.Web.Security.MembershipPasswordFormat Implements IMembershipProvider.PasswordFormat
        Get
            Return _passwordFormat
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordStrengthRegularExpression() As String Implements IMembershipProvider.PasswordStrengthRegularExpression
        Get
            Return _passwordStrengthRegularExpression
        End Get
    End Property

    Public Overrides ReadOnly Property RequiresQuestionAndAnswer() As Boolean Implements IMembershipProvider.RequiresQuestionAndAnswer
        Get
            Return _requiresQuestionAndAnswer
        End Get
    End Property

    Public Overrides ReadOnly Property RequiresUniqueEmail() As Boolean Implements IMembershipProvider.RequiresUniqueEmail
        Get
            Return _requiresUniqueEmail
        End Get
    End Property

    Public ReadOnly Property UserIsOnlineTimeWindow() As Integer Implements IMembershipProvider.UserIsOnlineTimeWindow
        Get
            Return _userIsOnlineTimeWindow
        End Get
    End Property

#End Region

#Region " Public Methods "

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overrides Sub Initialize(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection) Implements IMembershipProvider.Initialize

        PrepareConfigFromWebService(config)

        _enablePasswordRetrieval = config("enablepasswordretrieval")
        _enablePasswordReset = config("enablepasswordreset")
        _requiresQuestionAndAnswer = config("requiresquestionandanswer")
        _requiresUniqueEmail = config("requiresuniqueemail")
        _maxInvalidPasswordAttempts = config("maxinvalidpasswordattempts")
        _passwordAttemptWindow = config("passwordattemptwindow")
        _minRequiredPasswordLength = config("minrequiredpasswordlength")
        _minRequiredNonalphanumericCharacters = config("minrequirednonalphanumericcharacters")
        _passwordStrengthRegularExpression = config("passwordstrengthregularexpression")
        _userIsOnlineTimeWindow = config("userisonlinetimewindow")

        If config("passwordformat") IsNot Nothing Then
            _passwordFormat = CType([Enum].Parse(GetType(System.Web.Security.MembershipPasswordFormat), config("passwordformat")), System.Web.Security.MembershipPasswordFormat)
        Else
            _passwordFormat = System.Web.Security.MembershipPasswordFormat.Clear
        End If

        MyBase.Initialize(name, config)

    End Sub

    Public Overrides Function ChangePassword(ByVal username As String, ByVal oldPassword As String, ByVal newPassword As String) As Boolean Implements IMembershipProvider.ChangePassword
        Return _service.ChangePassword(_remoteProviderName, _applicationName, username, oldPassword, newPassword)
    End Function

    Public Overrides Function ChangePasswordQuestionAndAnswer(ByVal username As String, ByVal password As String, ByVal newPasswordQuestion As String, ByVal newPasswordAnswer As String) As Boolean Implements IMembershipProvider.ChangePasswordQuestionAndAnswer
        Return _service.ChangePasswordQuestionAndAnswer(_remoteProviderName, _applicationName, username, password, _
        newPasswordQuestion, newPasswordAnswer)
    End Function

    Public Overrides Function CreateUser(ByVal username As String, ByVal password As String, ByVal email As String, ByVal passwordQuestion As String, ByVal passwordAnswer As String, ByVal isApproved As Boolean, ByVal providerUserKey As Object, ByRef status As System.Web.Security.MembershipCreateStatus) As System.Web.Security.MembershipUser Implements IMembershipProvider.CreateUser
        Dim newStatus As MembershipProviderService.MembershipCreateStatus
        Dim user As System.Web.Security.MembershipUser = ConvertUser(_service.CreateUser(_remoteProviderName, _applicationName, username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, newStatus))
        status = CType([Enum].Parse(GetType(System.Web.Security.MembershipCreateStatus), newStatus.ToString()), System.Web.Security.MembershipCreateStatus)
        Return user
    End Function

    Public Overrides Function DeleteUser(ByVal username As String, ByVal deleteAllRelatedData As Boolean) As Boolean Implements IMembershipProvider.DeleteUser
        Return _service.DeleteUser(_remoteProviderName, _applicationName, username, deleteAllRelatedData)
    End Function

    Public Overrides Function FindUsersByEmail(ByVal emailToMatch As String, ByVal pageIndex As Integer, ByVal pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection Implements IMembershipProvider.FindUsersByEmail
        Return BuildUserCollection(_service.FindUsersByEmail(_remoteProviderName, _applicationName, emailToMatch, pageIndex, _
        pageSize, totalRecords))
    End Function

    Public Overrides Function FindUsersByName(ByVal usernameToMatch As String, ByVal pageIndex As Integer, ByVal pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection Implements IMembershipProvider.FindUsersByName
        Return BuildUserCollection(_service.FindUsersByName(_remoteProviderName, _applicationName, usernameToMatch, pageIndex, pageSize, totalRecords))
    End Function

    Public Overrides Function GetAllUsers(ByVal pageIndex As Integer, ByVal pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection Implements IMembershipProvider.GetAllUsers
        Return BuildUserCollection(_service.GetAllUsers(_remoteProviderName, _applicationName, pageIndex, pageSize, totalRecords))
    End Function

    Public Overrides Function GetNumberOfUsersOnline() As Integer Implements IMembershipProvider.GetNumberOfUsersOnline
        Return _service.GetNumberOfUsersOnline(_remoteProviderName, _applicationName)
    End Function

    Public Overrides Function GetPassword(ByVal username As String, ByVal answer As String) As String Implements IMembershipProvider.GetPassword
        Return _service.GetPassword(_remoteProviderName, _applicationName, username, answer)
    End Function

    Public Overloads Overrides Function GetUser(ByVal providerUserKey As Object, ByVal userIsOnline As Boolean) As System.Web.Security.MembershipUser Implements IMembershipProvider.GetUser
        Return ConvertUser(_service.GetUserByUserKey(_remoteProviderName, _applicationName, providerUserKey, userIsOnline))
    End Function

    Public Overloads Overrides Function GetUser(ByVal username As String, ByVal userIsOnline As Boolean) As System.Web.Security.MembershipUser Implements IMembershipProvider.GetUser
        Return ConvertUser(_service.GetUserByUsername(_remoteProviderName, _applicationName, username, userIsOnline))
    End Function

    Public Overrides Function GetUserNameByEmail(ByVal email As String) As String Implements IMembershipProvider.GetUserNameByEmail
        Return _service.GetUserNameByEmail(_remoteProviderName, _applicationName, email)
    End Function

    Public Overrides Function ResetPassword(ByVal username As String, ByVal answer As String) As String Implements IMembershipProvider.ResetPassword
        Return _service.ResetPassword(_remoteProviderName, _applicationName, username, answer)
    End Function

    Public Overrides Function UnlockUser(ByVal userName As String) As Boolean Implements IMembershipProvider.UnlockUser
        Return _service.UnlockUser(_remoteProviderName, _applicationName, userName)
    End Function

    Public Overrides Sub UpdateUser(ByVal user As System.Web.Security.MembershipUser) Implements IMembershipProvider.UpdateUser
        _service.UpdateUser(_remoteProviderName, _applicationName, ConvertUser(user))
    End Sub

    Public Overrides Function ValidateUser(ByVal username As String, ByVal password As String) As Boolean Implements IMembershipProvider.ValidateUser
        Return _service.ValidateUser(_remoteProviderName, _applicationName, username, password)
    End Function

#End Region

End Class
